11.2.1 基础理论

在顶层设计中,Docker网络架构由3个主要部分构成:CNM、Libnetwork和驱动。

CNM是设计标准。在CNM中,规定了Docker网络架构的基础组成要素。

Libnetwork是CNM的具体实现,并且被Docker采用。Libnetwork通过Go语言编写,并实现了CNM中列举的核心组件。

驱动通过实现特定网络拓扑的方式来拓展该模型的能力。

图11.1展示了顶层设计中的每个部分是如何组装在一起的。

54.png

图11.1 顶层设计

接下来具体介绍每部分的细节。

1.CNM

一切都始于设计!

Docker网络架构的设计规范是CNM。CNM中规定了Docker网络的基础组成要素,完整内容见GitHub的docker/libnetwork库。

推荐通篇阅读该规范,不过其实抽象来讲,CNM定义了3个基本要素:沙盒(Sandbox)、终端(Endpoint)和网络(Network)。

沙盒 是一个独立的网络栈。其中包括以太网接口、端口、路由表以及DNS配置。

终端 就是虚拟网络接口。就像普通网络接口一样,终端主要职责是负责创建连接。在CNM中,终端负责将沙盒连接到网络。

网络 是802.1d网桥(类似大家熟知的交换机)的软件实现。因此,网络就是需要交互的终端的集合,并且终端之间相互独立。

图11.2展示了3个组件是如何连接的。

55.png

图11.2 CNM

Docker环境中最小的调度单位就是容器,而CNM也恰如其名,负责为容器提供网络功能。图11.3展示了CNM组件是如何与容器进行关联的——沙盒被放置在容器内部,为容器提供网络连接。

56.png

图11.3 CNM组件与容器进行关联

容器A只有一个接口(终端)并连接到了网络A。容器B有两个接口(终端)并且分别接入了网络A和网络B。容器A与B之间是可以相互通信的,因为都接入了网络A。但是,如果没有三层路由器的支持,容器B的两个终端之间是不能进行通信的。

需要重点理解的是,终端与常见的网络适配器类似,这意味着终端只能接入某一个网络。因此,如果容器需要接入到多个网络,就需要多个终端。

图11.4对前面的内容进行拓展,加上了Docker主机。虽然容器A和容器B运行在同一个主机上,但其网络堆栈在操作系统层面是互相独立的,这一点由沙盒机制保证。

57.png

图11.4 加入Docker主机
2.Libnetwork

CNM是设计规范文档,Libnetwork是标准的实现。Libnetwork是开源的,采用Go语言编写,它跨平台(Linux以及Windows),并且被Docker所使用。

在Docker早期阶段,网络部分代码都存在于daemon当中。这简直就是噩梦——daemon变得臃肿,并且不符合UNIX工具模块化设计原则,即既能独立工作,又易于集成到其他项目。所以,Docker将该网络部分从daemon中拆分,并重构为一个叫作Libnetwork的外部类库。现在,Docker核心网络架构代码都在Libnetwork当中。

正如读者期望,Libnetwork实现了CNM中定义的全部3个组件。此外它还实现了本地服务发现(Service Discovery)、基于Ingress的容器负载均衡,以及网络控制层和管理层功能。

3.驱动

如果说Libnetwork实现了控制层和管理层功能,那么驱动就负责实现数据层。比如,网络连通性和隔离性是由驱动来处理的,驱动层实际创建网络对象也是如此,其关系如图11.5所示。

Docker封装了若干内置驱动,通常被称作原生驱动或者本地驱动。在Linux上包括 BridgeOverlay 以及 Macvlan ,在Windows上包括 NAT、OverlayTransport 以及 L2 Bridge 。接下来的一节中会介绍如何使用其中部分驱动。

58.png

图11.5 控制层、管理层与数据层的关系

第三方也可以编写Docker网络驱动。这些驱动叫作远程驱动,例如 CalicoContivKuryr 以及 Weave

每个驱动都负责其上所有网络资源的创建和管理。举例说明,一个叫作“prod-fe-cuda”的覆盖网络由 Overlay 驱动所有并管理。这意味着 Overlay 驱动会在创建、管理和删除其上网络资源的时候被调用。

为了满足复杂且不固定的环境需求,Libnetwork支持同时激活多个网络驱动。这意味着Docker环境可以支持一个庞大的异构网络。

results matching ""

    No results matching ""